package main.UI;

import main.UI.misc.ErrorHandling;
import main.UI.misc.PopupListener;
import main.database.DatabaseException;
import main.database.SQLDatabaseManager;
import main.database.entity.Category;
import main.database.entity.Expense;
import main.database.entity.MyEntity;
import main.database.entity.Product;
import org.jdesktop.swingx.JXDatePicker;

import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.*;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
 * Created with IntelliJ IDEA.
 * User: Sknictik
 * Date: 26.09.13
 * Time: 14:42
 * Main window.
 */
    //TODO Консоль
    //TODO Копирование записей
    //TODO Warning about things such as products with no category
public class GUI extends JFrame {
    private JPanel contentPane;
    private JButton exitButton;
    private JButton addButton;

    //Fields used to filter querry
    private JXDatePicker startDate;
    private JXDatePicker endDate;
 //   private JTextField categoryTextField;
    private JTextField filterTextField;

    private JButton filterSelectButton;
    private JTabbedPane entitiesTabs;
    private JTable expensesTable;
    private JTable productsTable;
    private JTable categoriesTable;
    private JButton deleteButton;
    private JButton categorySelectBtnForProducts;
    private JTextField filterTextFieldForProducts;
    private JMenuBar menuBar;
    private JMenuItem menuItem;

    private GUI gui = this;
    private static int changedRow;

    private static SQLDatabaseManager SQLManager;
    final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM-yyyy");
    //Values are not retrieved directly from interface components because
    //GUI.form needs to have them non-static. And because data is retrieved in static main method,
    //variables storing filter data need to be static.
    private static String startDateString;
    private static String endDateString;
    private static String filterForProducts = "Все";
    private static String filter = "Все";
    //private static boolean searchForCategory = false;
    private static Double summValue = 0.00;

    //Table models
    private static DefaultTableModel expensesTableModel;
    private static DefaultTableModel productsTableModel;
    private static DefaultTableModel categoriesTableModel;

    private static NumberFormat priceFormat;

    //TODO Unit testing
    //TODO Optimise
    //TODO сортировка по колонкам
    //TODO User should always has possibility to undo his action for this session and in this case Saving with unexpected program shutdown
    public static SQLDatabaseManager getSQLManager() {
        return SQLManager;
    }

    public GUI() {
            SQLManager = new SQLDatabaseManager();

            priceFormat = NumberFormat.getInstance();
            priceFormat.setMaximumFractionDigits(2);
            priceFormat.setMinimumFractionDigits(2);
            setTitle("Домашняя бухгалтерия");
            setResizable(false);
            setContentPane(contentPane);

            menuBar = new JMenuBar();

        JMenu menu = new JMenu("Файл");
            menuBar.add(menu);

            menuItem = new JMenuItem("Выход");
            menuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    onExit();
                }
            });
            menu.add(menuItem);

            menu = new JMenu("Расходы");

            menuItem = new JMenuItem("Добавить запись");
        //TODO MVC
            ActionListener addEntryAction = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (entitiesTabs.getSelectedIndex() == 0) {
                        ExpenseDialog expenseDialog = new ExpenseDialog();
                        expenseDialog.pack();
                        centerDialog(expenseDialog);
                        expenseDialog.setVisible(true);
                    }
                    else if (entitiesTabs.getSelectedIndex() == 1) {
                        try {
                        ProductDialog productDialog = new ProductDialog();
                        productDialog.pack();
                        centerDialog(productDialog);
                        productDialog.setVisible(true);
                        }
                        catch (DatabaseException ex) {
                            ErrorHandling.showError(ex, "Ошибка при обращении к базе данных", false);
                        }
                    }
                    else if (entitiesTabs.getSelectedIndex() == 2) {
                        CreateCategoryDialog categoryDialog = new CreateCategoryDialog();
                        categoryDialog.pack();
                        centerDialog(categoryDialog);
                        categoryDialog.setVisible(true);
                    }
                    }
        };

            menuItem.addActionListener(addEntryAction);

            menu.add(menuItem);

            menuItem = new JMenuItem("Изменить запись");
            ActionListener changeEntryAction = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (entitiesTabs.getSelectedIndex() == 0) {
                        changeExpense();
                    }
                    else if (entitiesTabs.getSelectedIndex() == 1) {
                        changeProduct();
                    }
                    else if (entitiesTabs.getSelectedIndex() == 2) {
                        changeCategory();
                    }
                }
            };
            menuItem.addActionListener(changeEntryAction);
            menu.add(menuItem);

            menuItem = new JMenuItem("Удалить запись");
            ActionListener deleteEntryAction = new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    int selectedType = entitiesTabs.getSelectedIndex();
                    Long id;
                    String entityType = "";
                    JTable curTable = null;

                    //Expenses
                    if (selectedType == 0)
                    {
                        curTable = expensesTable;
                        entityType = MyEntity.EXPENSE;
                    }
                    //Products
                    else if (selectedType == 1)
                    {
                        curTable = productsTable;
                        entityType = MyEntity.PRODUCT;
                    }
                    //Categories
                    else if (selectedType == 2)
                    {
                        curTable = categoriesTable;
                        entityType = MyEntity.CATEGORY;
                    }
                    //No row selected
                    int rowNum;
                    if (((rowNum = curTable.getSelectedRow()) == -1) ||
                            (curTable.equals(expensesTable) && rowNum == (curTable.getRowCount() - 1)))
                        return;
                    if (entityType.equals(MyEntity.EXPENSE)) {
                        String strID = (String) curTable.getValueAt(curTable.getSelectedRow(), 1);
                        strID = strID.replaceAll("<.*?>","");
                        id = Long.valueOf(strID);
                    }
                    else
                        id = (Long) curTable.getValueAt(curTable.getSelectedRow(), 1);

                    int result = JOptionPane.showOptionDialog(gui, "Вы уверены что хотите удалить эту запись?" ,
                            "Подтверждение", JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE,
                            null, new Object[] {"Да", "Нет"} , "Нет");
                    //If user says No - return
                    if (result == 1 || result == JOptionPane.CLOSED_OPTION)
                        return;

                    boolean isDeleted;
                    //Check if delete operation exceuted without errors
                    try {
                        isDeleted = SQLManager.removeEntityByID(entityType, id);
                    }
                    catch(DatabaseException e1) {
                        ErrorHandling.showError(e1, "Ошибка при удалении записи", false);
                        return;
                    }

                    if (isDeleted) {
                        DefaultTableModel curModel = (DefaultTableModel) curTable.getModel();
                        if (entityType.equals(MyEntity.EXPENSE))
                        {
                            String price = (String) curModel.getValueAt(rowNum, 5);
                            summValue -= stringPriceToNumber(price);
                            curModel.removeRow(curTable.getRowCount() - 1);
                            curModel.removeRow(rowNum);

                            if (curModel.getRowCount() != 0)
                                expensesTableModel.addRow(new Object[]{null, null, null, null, "<html><b>Итого</b></html>",
                                        priceFormat.format(summValue)});
                        }
                        else
                            curModel.removeRow(rowNum);
                    }
                }
        };

            menuItem.addActionListener(deleteEntryAction);
            menu.add(menuItem);

            menuBar.add(menu);

            //About window
            menu = new JMenu("?");

            menuItem = new JMenuItem("О программе");
            menuItem.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    AboutDialog aboutDlg = new AboutDialog();
                    aboutDlg.pack();
                    centerDialog(aboutDlg);
                    aboutDlg.setVisible(true);
                }
            });
            menu.add(menuItem);
            menuBar.add(menu);

            setJMenuBar(menuBar);


            //Expenses tab
            //---------------------------------------------------------------------
            expensesTableModel = new DefaultTableModel() {

                @Override
                public boolean isCellEditable(int row, int column) {
                    return false;
                }
            };

            expensesTable.getTableHeader().setReorderingAllowed(false);
            expensesTable.setModel(expensesTableModel);
            expensesTable.setRowHeight(20);



            expensesTableModel.addColumn("№");
            expensesTableModel.addColumn("ID");
            expensesTableModel.addColumn("Продукт");
            expensesTableModel.addColumn("Категория");
            expensesTableModel.addColumn("Дата");
            expensesTableModel.addColumn("Сумма");

            JPopupMenu popupMenu = new JPopupMenu();

            JMenuItem menuItem = new JMenuItem("Добавить запись");
            menuItem.addActionListener(addEntryAction);
            popupMenu.add(menuItem);

            menuItem = new JMenuItem("Изменить запись");
            menuItem.addActionListener(changeEntryAction);
            popupMenu.add(menuItem);

            menuItem = new JMenuItem("Удалить запись");
            menuItem.addActionListener(deleteEntryAction);
            popupMenu.add(menuItem);

            expensesTable.setComponentPopupMenu(popupMenu);

            // add the listener to the jtable
            MouseListener popupListener = new PopupListener();
            // add the listener specifically to the header
            expensesTable.addMouseListener(popupListener);
            expensesTable.getTableHeader().addMouseListener(popupListener);

            expensesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

            expensesTableModel.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                    if (e.getType() == TableModelEvent.INSERT) {
                        expensesTable.scrollRectToVisible(new Rectangle(expensesTable.getCellRect(
                                expensesTable.getRowCount() - 1, 0, true)));
                    }
                    else if (e.getType() == TableModelEvent.DELETE) {
                        for (int rowcnt = e.getLastRow(); rowcnt < expensesTable.getRowCount(); rowcnt++) {
                            expensesTable.setValueAt(rowcnt + 1, rowcnt, 0);
                        }
                    }
                }
        });

            expensesTable.registerKeyboardAction(deleteEntryAction,
                    KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);

            expensesTable.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getButton() == MouseEvent.BUTTON1)
                        if (e.getClickCount() == 2)
                        {
                            changeExpense();
                        }
                }
            });


            //datepicker
            try {

            //uncomment this code in production version
            //int year = Calendar.getInstance().get(Calendar.YEAR);
                //TODO today() - year : today()
            int year = 2013;
            startDate.setFormats("dd-MM-yyyy");
            startDate.setDate(DATE_FORMAT.parse("01-01-" + year));
            startDateString = DATE_FORMAT.format(startDate.getDate());

            startDate.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        if (startDate.getDate().getTime() > endDate.getDate().getTime()) {
                            startDate.setDate(endDate.getDate());
                            startDateString = DATE_FORMAT.format(startDate.getDate());
                            updateExpenseTable();
                            ErrorHandling.showWarning("Неправильный интервал");
                        }
                        startDateString = DATE_FORMAT.format(startDate.getDate());
                        updateExpenseTable();
                    }
                    catch (DatabaseException ex) {
                        ErrorHandling.showError(ex, "Ошибка при получении расходов из базы данных", false);
                    }
                }
            });
            endDate.setFormats("dd-MM-yyyy");
            endDate.setDate(DATE_FORMAT.parse("31-12-" + year));
            endDateString = DATE_FORMAT.format(endDate.getDate());

            endDate.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                    try {
                        if (endDate.getDate().getTime() < startDate.getDate().getTime()) {
                            endDate.setDate(startDate.getDate());
                            endDateString = DATE_FORMAT.format(endDate.getDate());
                            updateExpenseTable();
                            ErrorHandling.showWarning("Неправильный интервал");
                        }
                        else {
                            endDateString = DATE_FORMAT.format(endDate.getDate());
                            updateExpenseTable();
                        }
                    }
                    catch (DatabaseException ex) {
                        ErrorHandling.showError(ex, "Ошибка при получении расходов из базы данных", false);
                    }
                        }
                });
            }
            catch (ParseException e)
            {
                e.printStackTrace();
            }

            filterSelectButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    SelectEntryDialog dialog = new SelectEntryDialog(true, true);
                    centerDialog(dialog);
                    dialog.pack();
                    dialog.setVisible(true);

                    String value = dialog.getItem();
                    if (value.isEmpty())
                        return;
                    filterTextField.setText(dialog.getItem());
                    filter = dialog.getItem();
                    updateExpenseTable();
                }
                catch (DatabaseException ex) {
                    ErrorHandling.showError(ex, "Ошибка при обращении к базе данных", false);
                }
                }
        });

            //ProductTab
            //--------------------------------------------------------------------
            productsTableModel = new DefaultTableModel() {

                @Override
                public boolean isCellEditable(int row, int column) {
                return false;
            }
            };

            productsTable.getTableHeader().setReorderingAllowed(false);
            productsTable.setModel(productsTableModel);
            productsTable.setRowHeight(20);

            productsTableModel.addColumn("№");
            productsTableModel.addColumn("ID");
            productsTableModel.addColumn("Наименование");
            productsTableModel.addColumn("Категория");

            productsTable.setComponentPopupMenu(popupMenu);

            // add the listener to the jtable
            // add the listener specifically to the header
            productsTable.addMouseListener(popupListener);
            productsTable.getTableHeader().addMouseListener(popupListener);

            productsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

            productsTableModel.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                    if (e.getType() == TableModelEvent.INSERT) {
                        productsTable.scrollRectToVisible(new Rectangle(productsTable.getCellRect
                                (productsTable.getRowCount() - 1, 0, true)));
                    }
                    else if (e.getType() == TableModelEvent.DELETE) {
                        for (int rowcnt = e.getLastRow(); rowcnt < productsTable.getRowCount(); rowcnt++) {
                            productsTable.setValueAt(rowcnt + 1, rowcnt, 0);
                        }
                    }
                    }
            });

            productsTable.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (e.getButton() == MouseEvent.BUTTON1)
                        if (e.getClickCount() == 2)
                        {
                            changeProduct();
                        }
                }
            });

            categorySelectBtnForProducts.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        SelectEntryDialog dialog = new SelectEntryDialog(false, true);
                        centerDialog(dialog);
                        dialog.pack();
                        dialog.setVisible(true);

                        String value = dialog.getItem();
                        if (value.isEmpty())
                            return;
                        filterTextFieldForProducts.setText(dialog.getItem());
                        filterForProducts = dialog.getItem();
                        updateProductTable();
                    }
                    catch (DatabaseException ex) {
                        ErrorHandling.showError(ex, "Ошибка при обращении к базе данных", false);
                    }
                }
            });


            //CategoriesTab
            //--------------------------------------------------------------------
            categoriesTableModel = new DefaultTableModel() {

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

            categoriesTable.getTableHeader().setReorderingAllowed(false);
            categoriesTable.setModel(categoriesTableModel);
            categoriesTable.setRowHeight(20);

            categoriesTableModel.addColumn("№");
            categoriesTableModel.addColumn("ID");
            categoriesTableModel.addColumn("Наименование");

            categoriesTable.setComponentPopupMenu(popupMenu);

            // add the listener to the jtable
            // add the listener specifically to the header
            categoriesTable.addMouseListener(popupListener);


            categoriesTable.getTableHeader().addMouseListener(popupListener);

            //Если надо будет сделать выбор мышкой многих строк  сразу раскомментируй код ниже и убери setSelectionMode
            /*expensesTable.addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseDragged(MouseEvent e) {
                    expensesTable.addColumnSelectionInterval(0, 4);
                }
            });*/

            categoriesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

            categoriesTableModel.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                if (e.getType() == TableModelEvent.INSERT) {
                    categoriesTable.scrollRectToVisible(new Rectangle(
                            categoriesTable.getCellRect(categoriesTable.getRowCount() - 1, 0, true)));
                }
                else if (e.getType() == TableModelEvent.DELETE) {
                    for (int rowcnt = e.getLastRow(); rowcnt < categoriesTable.getRowCount(); rowcnt++) {
                        categoriesTable.setValueAt(rowcnt + 1, rowcnt, 0);
                    }
                }
                    }
            });

            categoriesTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getButton() == MouseEvent.BUTTON1)
                    if (e.getClickCount() == 2)
                    {
                        changeCategory();
                    }
                }
            });


            addButton.addActionListener(addEntryAction);

            deleteButton.addActionListener(deleteEntryAction);

            exitButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                onExit();
            }
        });

            // call onCancel() when cross is clicked
            setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    onExit();
                }
            });


        }

        private void onExit() {
            dispose();
        }

    public static void updateExpenseTable() throws DatabaseException{
        List expensesList;
        summValue = 0.00;
        expensesTableModel.setRowCount(0);

        Date startDate = null;
        Date endDate = null;
        try {
            startDate = DATE_FORMAT.parse(startDateString);
            endDate = DATE_FORMAT.parse(endDateString);
        }
        catch (ParseException ex) {
            ex.printStackTrace();
        }

        expensesList = SQLManager.getExpensesFromDB(filter, startDate, endDate);


        //Get all expenses from DB
        try {
                for (Object listItem : expensesList) {
                    Expense expense = (Expense) listItem;

                    String catName;
                    Category cat = expense.getProduct().getCategory();
                    if (cat == null)
                        catName = Category.NO_CATEGORY_WITH_TAGS;
                    else
                        catName = cat.getName();
                    addNewExpense(expense.getId(), expense.getProduct().getName(),
                            catName, DATE_FORMAT.format(expense.getDate()),
                            expense.getPrice());
                }
            }
        catch (NullPointerException e) {
            e.printStackTrace();
        }
    }


    public static void updateProductTable() throws DatabaseException {
        List productsList;
        productsTableModel.setRowCount(0);
        //Get all products from DB
        productsList = SQLManager.getFilteredProductsFromDB(filterForProducts);

        try {
                for (Object productItem : productsList) {
                    Product product = (Product) productItem;
                    String catName;
                    Category cat = product.getCategory();
                    if (cat == null)
                        catName = Category.NO_CATEGORY_WITH_TAGS;
                    else
                        catName = cat.getName();
                    addNewProduct(product.getId(), product.getName(),
                            catName);
                }

        }
        catch (NullPointerException e) {
            e.printStackTrace();
        }
    }


    public static void updateCategoryTable() throws DatabaseException{
        List categoriesList;
        categoriesTableModel.setRowCount(0);

            categoriesList = SQLManager.getAllEntriesFromDB(MyEntity.CATEGORY);


        //Get all categories from DB
        try {
                for (Object categoryItem : categoriesList) {
                    Category category = (Category) categoryItem;
                    addNewCategory(category.getId(), category.getName());
                }
        }
        catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    public static void addNewExpense(long id, String name, String type, String date, double price) {
        if (type == null) {
            type = Category.NO_CATEGORY_WITH_TAGS;
        }
        int row = expensesTableModel.getRowCount();
        if (row != 0)
            expensesTableModel.removeRow(row - 1);
        else
            row = 1;
        summValue += price;
        addEmphasisedRow(row, id, name, type, date, price);
        expensesTableModel.addRow(new Object[]{null, null, null, null, "<html><b>Итого</b></html>", "<html><b>"
                + priceFormat.format(summValue) + "</b></html>"});
    }

    public static void changeExpenseEntry(String name, String type, String date, Double price) {
        String formerPrice = (String) expensesTableModel.getValueAt(changedRow, 5);

        if (type == null) {
            type = Category.NO_CATEGORY_WITH_TAGS;
        }

        String startTag = "";
        String endTag = "";
        if (price <= 20) {
            startTag = "<html><font color=\"#808080\">";
            endTag = "</font></html>";
        }
        else if (price >= 15000){
            startTag = "<html><b>";
            endTag = "</b></html>";
        }

        expensesTableModel.setValueAt(addTags(startTag, endTag, name), changedRow, 2);
        expensesTableModel.setValueAt(addTags(startTag, endTag, type), changedRow, 3);
        expensesTableModel.setValueAt(addTags(startTag, endTag, date), changedRow, 4);

        expensesTableModel.setValueAt(addTags(startTag, endTag, priceFormat.format(price)), changedRow, 5);
        summValue -= stringPriceToNumber(formerPrice);
        summValue += price;

        expensesTableModel.removeRow(expensesTableModel.getRowCount() - 1);
        expensesTableModel.addRow(new Object[]{null, null, null, null, "<html><b>Итого</b></html>",
                priceFormat.format(summValue)});
    }


    public static void addNewProduct(long id, String name, String cat) {
        if (cat == null) {
            cat = Category.NO_CATEGORY_WITH_TAGS;
        }
        int row = productsTableModel.getRowCount();
        productsTableModel.addRow(new Object[]{row + 1, id, name, cat});
    }

    public static void changeProductEntry (String name, String cat) {
        if (cat.equals(Category.NO_CATEGORY)) {
            cat = Category.NO_CATEGORY_WITH_TAGS;
        }
        productsTableModel.setValueAt(name, changedRow, 2);
        productsTableModel.setValueAt(cat, changedRow, 3);
        try {
            updateExpenseTable();
        }
        catch (DatabaseException ex) {
            ErrorHandling.showError(ex, "Ошибка при получении расходов из базы данных", false);
        }
    }

    public static void addNewCategory(long id, String name) {
        int row = categoriesTableModel.getRowCount();
        if (name.equals(Category.NO_CATEGORY))
            name = Category.NO_CATEGORY_WITH_TAGS;
        categoriesTableModel.addRow(new Object[]{row + 1, id, name});
    }

    //@param name - new category name
    public static void changeCategoryEntry (String name) {
        categoriesTableModel.setValueAt(name, changedRow, 2);

        try {
            updateProductTable();
            updateExpenseTable();
        }
        catch (DatabaseException ex) {
            ErrorHandling.showError(ex, "Ошибка при изменении записей", false);
        }
    }

    private void changeExpense() {
        changedRow = expensesTable.getSelectedRow();
        if ((changedRow == -1) || (changedRow == expensesTable.getRowCount() - 1))
            return;
        //replaceAll strips value of HTML tags
        ExpenseDialog expenseDialog = new ExpenseDialog(Long.valueOf(
                ((String) expensesTable.getValueAt(changedRow, 1)).replaceAll("<.*?>","")),
                ((String) expensesTable.getValueAt(changedRow, 2)).replaceAll("<.*?>",""),
                ((String) expensesTable.getValueAt(changedRow, 4)).replaceAll("<.*?>",""),
                ((String) expensesTable.getValueAt(changedRow, 5)).replaceAll("<.*?>",""));
        expenseDialog.pack();
        centerDialog(expenseDialog);
        expenseDialog.setVisible(true);
    }

    private void changeProduct() {
        changedRow = productsTable.getSelectedRow();
        if (changedRow == -1)
            return;
        try {
            ProductDialog productDialog = new ProductDialog((Long) productsTable.getValueAt(changedRow, 1),
                    (String) productsTable.getValueAt(changedRow, 2),
                    (String) productsTable.getValueAt(changedRow, 3));
            productDialog.pack();
            centerDialog(productDialog);
            productDialog.setVisible(true);
        }
        catch (DatabaseException ex) {
            ErrorHandling.showError(ex, "Ошибка при обращении к базе данных", false);
        }
    }

    private void changeCategory() {
        changedRow = categoriesTable.getSelectedRow();
        if (changedRow == -1)
            return;
        try {
            CategoryPropertiesDialog categoryDialog = new CategoryPropertiesDialog((Long) categoriesTable.getValueAt(changedRow, 1),
                    (String) categoriesTable.getValueAt(changedRow, 2));
            categoryDialog.pack();
            centerDialog(categoryDialog);
            categoryDialog.setVisible(true);
        }
        catch (DatabaseException ex) {
            ErrorHandling.showError(ex, "Ошибка при обращении к базе данных", false);
        }
    }


    public static void centerDialog(Window dialog) {
        //Center the window
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = dialog.getSize();
        if (frameSize.height > screenSize.height) {
            frameSize.height = screenSize.height;
        }
        if (frameSize.width > screenSize.width) {
            frameSize.width = screenSize.width;
        }
        dialog.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
    }

    private static double stringPriceToNumber (String price) {
        price = price.replace(",", ".");
        price = price.replace("\u00a0","");    //Not replace " " because it was converted to HTML.
        price = price.replaceAll("<.*?>","");
        return Double.valueOf(price);
    }

    private static void addEmphasisedRow(int row, Long id, String name, String type, String date, Double price)
    {
        String startTag = "";
        String endTag = "";
        if (price <= 20) {
            startTag = "<html><font color=\"#808080\">";
            endTag = "</font></html>";
        }
        else if (price >= 15000){
            startTag = "<html><b>";
            endTag = "</b></html>";
        }
        expensesTableModel.addRow(new Object[]{addTags(startTag, endTag, row),
                addTags(startTag, endTag, id)
                , addTags(startTag, endTag, name)
                , addTags(startTag, endTag, type)
                , addTags(startTag, endTag, date)
                , addTags(startTag, endTag, priceFormat.format(price))});
    }

    private static String addTags(String startTag, String endTag, Object value) {
        return startTag + value + endTag;
    }


}

